﻿using Demo.Domains.Entities.Sys;
using Demo.PetaPoco.Application.DbContexts;
using Microsoft.Extensions.DependencyInjection;
using PetaPoco;
using PmSoft.Cache.Abstractions;
using PmSoft.Core;
using PmSoft.Data.Abstractions;
using PmSoft.Data.PetaPoco.Repositories;

namespace Demo.PetaPoco.Application.Services.User;

/// <summary>
/// 用户仓储类，提供用户数据的访问和缓存管理
/// </summary>
[Inject(ServiceLifetime.Scoped)]
public class UserRepository : CacheRepository<AppDbContext, SysUser, int>
{
	/// <summary>
	/// 构造函数
	/// </summary>
	/// <param name="dbContext">应用程序数据库上下文</param>
	/// <param name="applicationContext">应用程序上下文</param>
	public UserRepository(AppDbContext dbContext,
		IApplicationContext applicationContext)
		: base(dbContext, applicationContext)
	{
	}

	/// <summary>
	/// 判断手机号码是否存在
	/// </summary>
	/// <param name="mobile"></param>
	/// <returns></returns>
	public async Task<bool> ExistsByMobileAsync(string mobile)
	{
		return await DbContext.ExistsAsync<SysUser>("mobile=@0", mobile);
	}

	/// <summary>
	/// 判断电子邮箱是否存在
	/// </summary>
	/// <param name="email"></param>
	/// <returns></returns>
	public async Task<bool> ExistsByEmailAsync(string email)
	{
		return await DbContext.ExistsAsync<SysUser>("email=@0", email);
	}

	/// <summary>
	/// 根据手机号码获取用户信息
	/// </summary>
	/// <param name="mobile">手机号码</param>
	/// <returns>用户信息，如果未找到则返回null</returns>
	public async Task<SysUser?> GetUserByMobileAsync(string mobile)
	{
		Sql sql = Sql.Builder.Select("id").From("sys_user").Where("mobile=@0", mobile);
		var id = DbContext.FirstOrDefault<int>(sql);
		if (id == 0)
			return null;
		return await GetAsync(id);
	}

	/// <summary>
	/// 根据邮箱地址获取用户信息
	/// </summary>
	/// <param name="email">邮箱地址</param>
	/// <returns>用户信息，如果未找到则返回null</returns>
	public async Task<SysUser?> GetUserByEmailAsync(string email)
	{
		Sql sql = Sql.Builder.Select("id").From("sys_user").Where("email=@0", email);
		var id = DbContext.FirstOrDefault<int>(sql);
		if (id == 0)
			return null;
		return await GetAsync(id);
	}

	/// <summary>
	/// 获取指定部门的所有用户
	/// </summary>
	/// <param name="deptId">部门ID</param>
	/// <returns>用户集合</returns>
	/// <remarks>
	/// 使用缓存机制，通过部门区域版本号来管理缓存
	/// 缓存键格式：Users:{deptId}:{areaVersion}
	/// 最多返回1000条记录
	/// </remarks>
	public async ValueTask<IEnumerable<SysUser>> GetUsersAsync(int deptId)
	{
		int areaVersion = await CacheVersionService.GetAreaVersionAsync(m => m.DeptId, deptId);
		return await GetTopEntitiesWithCacheAsync(1000,
			CachingExpirationType.ObjectCollection,
			() => $"Users:{deptId}:{areaVersion}",
			() =>
			{
				Sql sql = Sql.Builder.Select("id").From("sys_user").Where("dept_id=@0", deptId);
				return sql;
			});
	}

	/// <summary>
	/// 分页查询用户列表
	/// </summary>
	/// <param name="query">查询条件对象</param>
	/// <returns>分页后的用户列表</returns>
	/// <remarks>
	/// 支持按用户名模糊查询和部门ID精确查询
	/// 结果按用户ID升序排序
	/// </remarks>
	public async ValueTask<IPagedList<SysUser>> UserPagingAsync(UserQuery query)
	{
		Sql sql = Sql.Builder
		.Select("id")
		.From("sys_user");

		if (!string.IsNullOrWhiteSpace(query.Mobile))
			sql.Where("mobile like @0", "%" + query.Mobile + "%");

		if (!string.IsNullOrWhiteSpace(query.Email))
			sql.Where("email like @0", "%" + query.Email + "%");

		if (query.DeptId.HasValue)
			sql.Where("dept_id=@0", query.DeptId);

		if (query.UserType.HasValue)
			sql.Where("type=@0", query.UserType);

		sql.OrderBy("id desc");

		return await GetPagedEntitiesAsync(sql,
		   query.PageIndex,
		   query.PageSize
		   );
	}
}
